#include"http.hpp"
//#include"../server.hpp"
using namespace std;
//  size_t Split(const std::string& str, const std::string& delim, std::vector<std::string>* result) {
// // str是要分割的字符串，delim是分隔符，result是存储分割结果的容器
  
//   size_t offset = 0;//偏移量-当前指向位置下标
//   while(offset < str.size()) {
//     size_t pos = str.find(delim, offset);//查找分隔符位置
    
//     if (pos == std::string::npos) {//如果没找到
//      if(pos==str.size())break;//如果分隔符在字符串末尾则不添加
     
//         result->push_back(str.substr(offset));//将剩余部分添加到结果中
//       return result->size(); // 返回分割后的部分数量
//     }
//     if(pos == offset) {//如果分隔符在开头
//       offset += delim.size(); // 跳过分隔符
//       continue; // 继续查找下一个分隔符
//     }
//     result->push_back(str.substr(offset, pos - offset));//将分隔符前的部分添加到结果中
//     offset = pos + delim.size();//更新偏移量
//   }
//   return result->size(); // 返回分割后的部分数量

// }


// bool ReadFile(const std::string& filename, std::string* content) {
//     assert(content != nullptr);
//     std::ifstream ifs(filename,std::ios::binary);// 打开文件,以二进制方式读取
//     if(ifs.is_open()==false) {
//         printf("open file %s failed\n", filename.c_str());
//         return false;
//     }

//     ifs.seekg(0, std::ios::end); // 移动到文件末尾
//     size_t size = ifs.tellg(); // 获取文件大小
//     ifs.seekg(0, std::ios::beg); // 移动到文件开头
//     content->resize(size); // 调整内容大小
//     ifs.read(&(*content)[0], size); // 读取文件内容到字符串
//     if(ifs.good() == false) {
//         printf("read file %s failed\n", filename.c_str());
//         return false;
//     }

//     ifs.close(); // 关闭文件
//     return true;
//   }

// bool ReadFile(const std::string& filename, std::string* content) {
//     assert(content != nullptr);
//     std::ifstream ifs(filename,std::ios::binary);// 打开文件,以二进制方式读取
//     if(ifs.is_open()==false) {
//         printf("open file %s failed\n", filename.c_str());
//         return false;
//     }

//     ifs.seekg(0, std::ios::end); // 移动到文件末尾
//     size_t size = ifs.tellg(); // 获取文件大小
//     ifs.seekg(0, std::ios::beg); // 移动到文件开头
//     content->resize(size); // 调整内容大小
//     ifs.read(&(*content)[0], size); // 读取文件内容到字符串
//     if(ifs.good() == false) {
//         printf("read file %s failed\n", filename.c_str());
//         return false;
//     }

//     ifs.close(); // 关闭文件
//     return true;
//   }

  // static bool WriteFile(const std::string& filename, const std::string& content) {
  //   std::ofstream ofs(filename,std::ios::binary|std::ios::trunc); // 打开文件,以二进制方式写入,清空文件内容
  //   if(!ofs.is_open()) {
  //       printf("open file %s failed\n", filename.c_str());
  //       return false; 
  //   }

  //   ofs.write(content.data(), content.size()); // 写入内容到文件
  // if(ofs.good() == false) {
  //       printf("write file %s failed\n", filename.c_str());
  //       return false;
  //   }

  //   ofs.close(); // 关闭文件
  //   return true;
  
  // }

//  std::string StatuDesc(int statu){
//   std::unordered_map<int,std::string> uuu={
//     {100, "Continue"},
// {101, "Switching Protocol"},
//  {102, "Processing"},
//  {103, "Early Hints"},
//  {200, "OK"},
//  {201, "Created"},
//  {202, "Accepted"},
//  {203, "Non-Authoritative Information"},
//  {204, "No Content"},
//  {205, "Reset Content"},
//  {206, "Partial Content"},
//  {207, "Multi-Status"},
//  {208, "Already Reported"},
//  {226, "IM Used"},
//  {300, "Multiple Choice"},
//  {301, "Moved Permanently"},
//  {302, "Found"},
//  {303, "See Other"},
//  {304, "Not Modified"},
//  {305, "Use Proxy"},
//  {306, "unused"},
//  {307, "Temporary Redirect"},
//  {308, "Permanent Redirect"},
//  {400, "Bad Request"},
//  {401, "Unauthorized"},
//  {402, "Payment Required"},
//  {403, "Forbidden"},
//  {404, "Not Found"},
//  {405, "Method Not Allowed"},
//  {406, "Not Acceptable"},
//  {407, "Proxy Authentication Required"},
//  {408, "Request Timeout"},
//  {409, "Conflict"},
//  {410, "Gone"},
//  {411, "Length Required"},
//  {412, "Precondition Failed"},
//  {413, "Payload Too Large"},
//  {414, "URI Too Long"},
//  {415, "Unsupported Media Type"},
//  {416, "Range Not Satisfiable"},
//  {417, "Expectation Failed"},
//  {418, "I'm a teapot"},
//  {421, "Misdirected Request"},
//  {422, "Unprocessable Entity"},
//  {423, "Locked"},
//  {424, "Failed Dependency"},
//  {425, "Too Early"},
//  {426, "Upgrade Required"},
//  {428, "Precondition Required"},
//  {429, "Too Many Requests"},
//  {431, "Request Header Fields Too Large"},
//  {451, "Unavailable For Legal Reasons"},
//  {501, "Not Implemented"},
//  {502, "Bad Gateway"},
//  {503, "Service Unavailable"},
//  {504, "Gateway Timeout"},
//  {505, "HTTP Version Not Supported"},
//  {506, "Variant Also Negotiates"},
//  {507, "Insufficient Storage"},
//  {508, "Loop Detected"},
//  {510, "Not Extended"},
//  {511, "Network Authentication Required"}
//   };

//   auto it = uuu.find(statu);
//   if(it != uuu.end()) {
//     return it->second;
//   } else {
//     return "Unknown Status";
//  }
// }

//   std::string UrlEncode(const std::string &url,bool convert_sapce_to_plus = false) {
//     std::string encoded;
//     for (char c : url) {
//         if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~'||isalnum(c)) {
//             encoded += c; // 保留字母、数字和某些特殊字符
//             continue;
//         } else if (c == ' ' && convert_sapce_to_plus) {
//             encoded += '+'; // 将空格转换为加号
//             continue;
//         } else {
//             char buf[4]={0};
//             snprintf(buf, sizeof(buf), "%%%02X", static_cast<unsigned char>(c)); //%%%02X格式化字符为十六进制--%%为转义字符将%输出为%，%02X将字符转换为两位十六进制数,0为前补零，2为两位
//             encoded += buf;
//         }
//     }
//     return encoded;
//   }
//  char Decodechar(char c){
//   if(c >= '0' && c <= '9') {
//     return c - '0'; // 数字字符转换为对应的整数值
//   } else if(c >= 'A' && c <= 'F') {
//     return c - 'A' + 10; // 大写字母转换为对应的整数值
//   } else if(c >= 'a' && c <= 'f') {
//     return c - 'a' + 10; // 小写字母转换为对应的整数值
//   }
//   printf("decode char %c failed\n", c);
//   return -1;
// }

//  std::string UrlDecode(const std::string &url,bool convert_sapce_to_plus = false) {
//     std::string decoded;
//     for (size_t i = 0; i < url.size(); ++i) {
//       if(convert_sapce_to_plus && url[i] == '+') {
//             decoded += ' '; // 将加号转换为空格
//             continue;
//         }
//         if (url[i] == '%') {
//            decoded+=Decodechar(url[i + 1]) * 16 + Decodechar(url[i + 2]); // 将%后面的两位十六进制数转换为字符
//             i += 2; // 跳过已处理的两个字符
//         }
//     }
//     return decoded;
//   }

//  bool IsDirectory(const std::string& path) {
//     struct stat statbuf;
//     int ret=stat(path.c_str(), &statbuf);
//     if(ret<0)return false; // 如果stat失败，返回false
//     return S_ISDIR(statbuf.st_mode); // 检查路径是否为目录
//   }

//  bool IsFile(const std::string& path) {
//     struct stat statbuf;
//     int ret=stat(path.c_str(), &statbuf);
//     if(ret<0)return false; // 如果stat失败，返回false
//     return S_ISREG(statbuf.st_mode); // 检查路径是否为常规文件
//   }

//  bool ValidPath(const std::string& path) {
//     if(path.empty()) return false; // 路径不能为空
//     std::vector<std::string> parts;
//     Split(path, "/", &parts); // 分割路径
//     int level = 0; // 路径层级
//     for(const auto& part : parts) {
//       if(part=="..") {
//        level--; // 上一级目录
//         if(level < 0) return false; // 如果层级小于0，路径无效
//         continue;
//       }
//       level++;
//     }
//     return true; // 如果遍历完所有部分，路径有效
//   }

// int main()
// {
//   std::cout<<ValidPath("/test/../test2/")<<std::endl; // 检查路径是否有效
//   std::cout<<ValidPath("/test/../../vvv.cpp")<<std::endl;

// // std::cout<<IsDirectory("./")<<std::endl; // 检查当前目录是否为目录
// // std::cout<<IsDirectory("test.cc")<<std::endl; // 检查当前目录是否为目录
// // std::cout<<IsFile("./")<<std::endl; // 检查当前目录是否为目录
// // std::cout<<IsFile("test.cpp")<<std::endl; // 检查当前目录是否为目录
// //   string str="C++";
// //   string tmp=UrlEncode(str,true);
// //   cout<<"before encode: " << str << endl;
// //   cout<<"after encode: " << tmp << endl;

// // string str2=UrlDecode(tmp,true);
// // cout<<"after decode: " << str2 << endl;

//     // string strr="hello,,,,,,world,how,are,you,,,";
//     // string delim=",";
//     // vector<string> result;
//     // size_t count = Split(strr, delim, &result);
    
//     // for(auto ret: result) {
//     //     cout <<"[" <<ret<<"]" << endl; // 输出分割后的结果
//     // }

//   //  std:: string buf;
//   //   bool ret = ReadFile("./http.hpp", &buf);

//   //   if(ret==false)return -1;

//   //   bool ret2 = WriteFile("./testtt.C", buf);
//   //   if(ret2==false)return -1;
//    // std::cout << "File content:\n" << buf << std::endl;
//     return 0;
// }

#define WWWROOT "./wwwroot"
std::string Requeststr(const HttpRequest&req)
{
  std::stringstream ss;
  ss<<req._method<<" "<<req._path<<" "<<req._version<<"\r\n";
  for(auto&it :req._query_params)//查询字符串
  {
    ss<<it.first<<":"<<it.second<<"\r\n";   
  }
  for(auto&it :req._headers)//请求头部
  {
    ss<<it.first<<":"<<it.second<<"\r\n";   
  }
  ss<<"\r\n";
  ss<<req._body;
  return ss.str();

}

void Hello(const HttpRequest&req,HttpResponse*rsp)
{
  rsp->SetContext(Requeststr(req),"text/plain");

}

void Post(const HttpRequest&req,HttpResponse*rsp)
{
  rsp->SetContext(Requeststr(req),"text/plain");

}

void PutFile(const HttpRequest&req,HttpResponse*rsp)
{
  rsp->SetContext(Requeststr(req),"text/plain");

}

void DeleteFile(const HttpRequest&req,HttpResponse*rsp)
{
  rsp->SetContext(Requeststr(req),"text/plain");

}


int main()
{
  HttpServer server(8080);
  server.SetThreadCount(0);
  server.SetBasedir(WWWROOT);
  server.Get("/hello", Hello);
  server.Post("/postlogin", Post);
  server.Put("/Pput.txt", PutFile);
  server.Delete("/Pput.txt", DeleteFile);
  DBG_LOG("server ready listen");
 
  server.Listen();




  return 0;
}
